home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 20
/
Aminet 20 (1997)(GTI - Schatztruhe)[!][Aug 1997].iso
/
Aminet
/
hard
/
drivr
/
vbak2091.lha
/
vb2091.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-06-25
|
9KB
|
283 lines
/* vb2091 0.3 (c) in 1994 by Volker Barthelmann */
#include <string.h>
#include <exec/execbase.h>
#include <exec/memory.h>
#include <exec/io.h>
#include <exec/semaphores.h>
#include <devices/trackdisk.h>
#include <devices/timer.h>
#include <dos/dosextens.h>
#include <dos/filehandler.h>
#include <dos/dostags.h>
#include <clib/exec_protos.h>
#include <clib/alib_protos.h>
#include <clib/dos_protos.h>
#define MAXUNIT 8
char zahl[]="0123456789";
struct IOStdReq *IO[MAXUNIT];
struct SignalSemaphore *ss;
#define DEV_BEGINIO (-30)
#define min(a,b) ((a) < (b) ? (a) : (b))
#define STAY 1
#define BROKEN 2
#define SINGLEF 4
#define NOCACHE 8
#define NOWRITE 16
void (*oldbeginio)(__reg("a1") struct IOStdReq *, __reg("a6") struct Device *);
void (*oldarray[8])();
void *Unit[MAXUNIT];
int SIZE=262144,msize,flags,UnitNr,unitmask;
int MAXN=16,MIN1BUF=131072,MIN2BUF=65536;
char *buffer;
struct MsgPort *iosink[MAXUNIT];
void mybeginio(__reg("a1") struct IOStdReq *req,__reg("a6") struct Device *dev)
{
struct MsgPort *port;
struct IOStdReq *mreq;
unsigned int actual,data,offset,length,lactual,ldata,flag,msize;
int un=-1;
geta4();
mreq=req;
ObtainSemaphore(ss);
for(flag=0;flag<MAXUNIT;flag++)
if(req->io_Unit==Unit[flag])
un=flag;
if(un==-1) goto old;
/* oldbeginio=oldarray[un];*/
if((req->io_Command & 0xFF) == CMD_READ){
if((flags & BROKEN)==0 && (unsigned long) req->io_Data<16777216)
goto old;
port=(struct MsgPort *)CreatePort(NULL,0);
IO[un]->io_Message.mn_ReplyPort=port;
actual=0;
length=mreq->io_Length;
if(length>MIN2BUF*MAXN){
msize=min((length+MAXN-1)/MAXN,SIZE/2);
}else{
if(length<MIN1BUF) msize=min(length,SIZE/2);
else msize=min(MIN2BUF,SIZE/2);
}
if(msize>=512) msize&=0xfffffe00;
offset=mreq->io_Offset;
data=(unsigned int) mreq->io_Data;
lactual=flag=0;ldata=data;
if(flags&NOCACHE) CacheControl(0,CACRF_EnableD);
do{
IO[un]->io_Offset=offset;
if(flags&SINGLEF){
IO[un]->io_Length=min(SIZE,length);
IO[un]->io_Data=buffer;
}else{
IO[un]->io_Length=min(msize,length);
if(flag==0) IO[un]->io_Data=buffer; else
IO[un]->io_Data=buffer+SIZE/2;
}
IO[un]->io_Command=CMD_READ;
oldbeginio(req=IO[un],IO[un]->io_Device);
if((flags&SINGLEF)==0){
if(flag!=0) CopyMem(buffer,(APTR) ldata,lactual);
else CopyMem(buffer+SIZE/2,(APTR) ldata,lactual);
}
WaitIO((struct IORequest *) IO[un]);
actual+=IO[un]->io_Actual;lactual=IO[un]->io_Actual;
ldata=data;data+=IO[un]->io_Actual;
offset+=IO[un]->io_Actual;
length-=IO[un]->io_Actual;
flag=1-flag;
if(flags&SINGLEF) CopyMem(buffer,(APTR) ldata,lactual);
}while(length>0 && IO[un]->io_Actual>=IO[un]->io_Length);
if((flags&SINGLEF)==0){
if(flag!=0) CopyMem(buffer,(APTR) ldata,lactual);
else CopyMem(buffer+SIZE/2,(APTR) ldata,lactual);
}
if(flags&NOCACHE) CacheControl(0xffffffff,CACRF_EnableD);
mreq->io_Actual=actual;
mreq->io_Error=IO[un]->io_Error;
DeletePort(port);
if(!(mreq->io_Flags & IOF_QUICK))
ReplyMsg(&mreq->io_Message);
ReleaseSemaphore(ss);
return;
}
if((req->io_Command & 0xFF) == CMD_WRITE){
if(flags&NOWRITE) goto old;
if((flags & BROKEN)==0 && (unsigned long) req->io_Data<16777216)
goto old;
port=(struct MsgPort *)CreatePort(NULL,0);
IO[un]->io_Message.mn_ReplyPort=port;
actual=0;
length=mreq->io_Length;
offset=mreq->io_Offset;
data=(unsigned int) mreq->io_Data;
if(flags&NOCACHE) CacheControl(0,CACRF_EnableD);
do{
if(SIZE>=length) IO[un]->io_Length=length; else
IO[un]->io_Length=SIZE;
CopyMem((APTR) data,buffer,IO[un]->io_Length);
IO[un]->io_Offset=offset;
IO[un]->io_Data=buffer;
IO[un]->io_Command=CMD_WRITE;
oldbeginio(req=IO[un],IO[un]->io_Device);
WaitIO((struct IORequest *) IO[un]);
actual+=IO[un]->io_Actual;
data+=IO[un]->io_Actual;
offset+=IO[un]->io_Actual;
length-=IO[un]->io_Actual;
}while(length>0 && IO[un]->io_Actual>=IO[un]->io_Length);
if(flags&NOCACHE) CacheControl(0xffffffff,CACRF_EnableD);
mreq->io_Actual=actual;
mreq->io_Error=IO[un]->io_Error;
DeletePort(port);
if(!(mreq->io_Flags & IOF_QUICK))
ReplyMsg(&mreq->io_Message);
ReleaseSemaphore(ss);
return;
}
old:
oldbeginio(req,dev);
ReleaseSemaphore(ss);
}
int
main(int argc, char *argv[])
{
long tmp;
BPTR op;
int devopen,i;
char *Device="2nd.scsi.device",*p;
tmp = 0;
devopen = 0;
op=Output();
for(i=1; i<argc; i++){
/*printf("Arg: %d %s: ",i,argv[i]);*/
if(!strcmp("BUFSIZE",argv[i])){
SIZE=atoi(argv[++i])*1024;continue;}
if(!strcmp("MIN1BUF",argv[i])){
MIN1BUF=atoi(argv[++i])*1024;continue;}
if(!strcmp("MIN2BUF",argv[i])){
MIN2BUF=atoi(argv[++i])*1024;continue;}
if(!strcmp("MAXN",argv[i])){
MAXN=atoi(argv[++i]);continue;}
if(!strcmp("DEVICE",argv[i])){
Device=argv[++i];continue;}
if(!strcmp("UNIT",argv[i])){
p=argv[++i];
while(*p!=0){
if(*p<'0'||*p>'7') {Write(op,"You can only use unit 0..7!!\n",29L);exit(0);}
unitmask|=1<<(*p-'0');
p++;
}
continue;}
if(!strcmp("BROKEN",argv[i])){
flags|=BROKEN;continue;}
if(!strcmp("SINGLE",argv[i])){
flags|=SINGLEF;continue;}
if(!strcmp("NOCACHE",argv[i])){
flags|=NOCACHE;continue;}
if(!strcmp("NOWRITE",argv[i])){
flags|=NOWRITE;continue;}
Write(op,"Wrong argument: ",16L);
Write(op,argv[i],strlen(argv[i]));
Write(op,"\nPLEASE READ THE MANUAL !!\n",27L);
exit(0);
}
Write(op,"vb2091 V0.3 (c) in 1994,1996 by Volker Barthelmann\n",52L);
/*printf("Flags: %d SIZE: %d Device: %s\n",flags,SIZE,Device);*/
/*printf("unitmask: %d\n",unitmask);*/
for(i=0;i<MAXUNIT;i++){
if((unitmask&(1<<i))==0) continue;
iosink[i] = (struct MsgPort *)CreatePort(NULL, 0);
IO[i] = (struct IOStdReq *) CreateExtIO(iosink[i], sizeof (*IO[0]));
tmp = OpenDevice(Device, i, (struct IORequest *) IO[i], 0);
if (tmp) {
Write(op,"Unable to open ",15L);
Write(op,Device,strlen(Device));
Write(op," Unit ",6L);Write(op,&(zahl[i]),1L);
Write(op,"\n",1L);
/* if(IO[i])DeleteExtIO((struct IORequest *) IO[i]);
if(iosink[i]) DeletePort(iosink[i]); */
IO[i]=0;
continue;
} else{
Write(op,"Opened ",7L);
Write(op,Device,strlen(Device));
Write(op," Unit ",6L);Write(op,&(zahl[i]),1L);
Write(op,"\n",1L);
devopen = 1;
/*printf("Opened %s unit %d\n",Device,i);*/
SumLibrary((struct Library *) IO[i]->io_Device);
/* oldarray[i] = (void (* )()) SetFunction((struct Library *) IO[i]->io_Device, DEV_BEGINIO, (APTR) &mybeginio);*/
if(!oldbeginio) oldbeginio = (void (* )()) SetFunction((struct Library *) IO[i]->io_Device, DEV_BEGINIO, (APTR) &mybeginio);
Unit[i]=IO[i]->io_Unit;
}
}
ss = (struct SignalSemaphore *)AllocMem(sizeof (struct SignalSemaphore), MEMF_PUBLIC);
if (!ss)
goto quit;
InitSemaphore(ss);
if(flags&BROKEN)
buffer=(char *)AllocMem(SIZE,MEMF_24BITDMA|MEMF_FAST|MEMF_PUBLIC);
else
buffer=(char *)AllocMem(SIZE,MEMF_24BITDMA|MEMF_PUBLIC);
if(buffer==0) {Write(op,"Cannot allocate buffer!!\n",25L);goto quit;}
if(devopen) Wait(SIGBREAKF_CTRL_C);
quit:
ObtainSemaphore(ss);
for(i=MAXUNIT-1;i>=0;i--){
/* if(IO[i]) printf("Restoring Unit %d\n",i);*/
/* if(IO[i]) SetFunction((struct Library *) IO[i]->io_Device, DEV_BEGINIO, (APTR) oldarray[i]);*/
if(IO[i]) SetFunction((struct Library *) IO[i]->io_Device, DEV_BEGINIO, (APTR) oldbeginio);
}
ReleaseSemaphore(ss);
if(buffer)
FreeMem(buffer, SIZE);
if (ss)
FreeMem(ss, sizeof (struct SignalSemaphore));
for(i=0;i<MAXUNIT;i++){
if (devopen) {
if(IO[i]) CloseDevice((struct IORequest *) IO[i]);
}
if (IO[i])
DeleteExtIO((struct IORequest *) IO[i]);
if (iosink[i])
DeletePort(iosink[i]);
}
return 0;
}